#ifndef __MSGQUEUE_H__
#define __MSGQUEUE_H__

#include <string>
#include <functional>
#include "plat/nonecopyable.h"

#define MSGQ_MAX_SIZE_DEFAULT 10

class MsgQueueImpl : public NoneCopyable
{
public:
    explicit MsgQueueImpl();
    virtual ~MsgQueueImpl();

public:
    void Create(uint32_t max, uint32_t itemSize);
    bool Post(void *data, int timeout = -1);
    bool Wait(void *data, int timeout = -1);
    void Clear();
    
    int GetCount();
    int GetSpace();
    int GetCapacity();

private:
    void CreateQ(uint32_t max, uint32_t itemSize);
    void DeleteQ();

private:
    void *m_qHandle = nullptr;
};

//void *模式
class MsgQueueVoid : public MsgQueueImpl
{
public:
    explicit MsgQueueVoid(uint32_t max, uint32_t itemSize)
    {
        Create(max, itemSize);
    }

    virtual ~MsgQueueVoid()
    {

    }
};

template<typename T, int MQ_MAX_SIZE = MSGQ_MAX_SIZE_DEFAULT>
class MsgQueue : public NoneCopyable
{
public:
    explicit MsgQueue(uint32_t max = MQ_MAX_SIZE)
    {
        Create(max);
    }

    virtual ~MsgQueue()
    {
        
    }

public:
    void Create(uint32_t max)
    {
        m_msgQImpl.Create(max, sizeof(T));
    }

    //post 默认不等待 [因为中断里面post，不能等待]
    bool Post(T data, int timeout = 0)
    {
        return m_msgQImpl.Post((void*)&data, timeout);
    }

    bool Wait(T &data, int timeout = -1)
    {
        return m_msgQImpl.Wait((void*)&data, timeout);
    }

    void Clear()
    {
        m_msgQImpl.Clear();
    }
    
    int GetCount()
    {
        return m_msgQImpl.GetCount();
    }

    int GetSpace()
    {
        return m_msgQImpl.GetSpace();
    }

    int GetCapacity()
    {
        return m_msgQImpl.GetCapacity();
    }

private:
    MsgQueueImpl m_msgQImpl;
};

#endif // __MSGQUEUE_H__
